home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / osr5 / devtools / dejagnu-971222 / usr / local / share / dejagnu / framework.exp < prev    next >
Encoding:
Text File  |  1998-03-22  |  18.0 KB  |  779 lines

  1. # Copyright (C) 92, 93, 94, 95, 1996, 1997 Free Software Foundation, Inc.
  2.  
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 2 of the License, or
  6. # (at your option) any later version.
  7. # This program is distributed in the hope that it will be useful,
  8. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10. # GNU General Public License for more details.
  11. # You should have received a copy of the GNU General Public License
  12. # along with this program; if not, write to the Free Software
  13. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14.  
  15. # Please email any bugs, comments, and/or additions to this file to:
  16. # bug-dejagnu@prep.ai.mit.edu
  17.  
  18. # This file was written by Rob Savoye. (rob@cygnus.com)
  19.  
  20. # These variables are local to this file.
  21. # This or more warnings and a test fails.
  22. set warning_threshold 3
  23. # This or more errors and a test fails.
  24. set perror_threshold 1
  25.  
  26. proc mail_file { file to subject } {
  27.     if [file readable $file] {
  28.     catch "exec mail -s \"$subject\" $to < $file"
  29.     }
  30. }
  31.  
  32. #
  33. # Open the output logs
  34. #
  35. proc open_logs { } {
  36.     global outdir
  37.     global tool
  38.     global sum_file
  39.     
  40.     if { ${tool} ==  "" } {
  41.     set tool testrun
  42.     }
  43.     catch "exec rm -f $outdir/$tool.sum"
  44.     set sum_file [open "$outdir/$tool.sum" w]
  45.     catch "exec rm -f $outdir/$tool.log"
  46.     log_file -a "$outdir/$tool.log"
  47.     verbose "Opening log files in $outdir"
  48.     if { ${tool} ==  "testrun" } {
  49.     set tool ""
  50.     }
  51. }
  52.  
  53.  
  54. #
  55. # Close the output logs
  56. #
  57. proc close_logs { } {
  58.     global sum_file
  59.     
  60.     catch "close $sum_file"
  61. }
  62.  
  63. #
  64. # Check build host triplet for pattern
  65. #
  66. # With no arguments it returns the triplet string.
  67. #
  68. proc isbuild { pattern } {
  69.     global build_triplet
  70.     global host_triplet
  71.     
  72.     if ![info exists build_triplet] {
  73.     set build_triplet ${host_triplet}
  74.     }
  75.     if [string match "" $pattern] {
  76.     return $build_triplet
  77.     }
  78.     verbose "Checking pattern \"$pattern\" with $build_triplet" 2
  79.     
  80.     if [string match "$pattern" $build_triplet] {
  81.     return 1
  82.     } else {
  83.     return 0
  84.     }
  85. }
  86.  
  87. #
  88. # Is $board remote? Return a non-zero value if so.
  89. #
  90. proc is_remote { board } {
  91.     global host_board;
  92.     global target_list;
  93.  
  94.     verbose "calling is_remote $board" 3;
  95.     # Remove any target variant specifications from the name.
  96.     set board [lindex [split $board "/"] 0];
  97.  
  98.     # Map the host or build back into their short form.
  99.     if { [board_info build name] == $board } {
  100.     set board "build";
  101.     } elseif { [board_info host name] == $board } {
  102.     set board "host";
  103.     }
  104.  
  105.     # We're on the "build". The check for the empty string is just for
  106.     # paranoia's sake--we shouldn't ever get one. "unix" is a magic
  107.     # string that should really go away someday.
  108.     if { $board == "build" || $board == "unix" || $board == "" } {
  109.     verbose "board is $board, not remote" 3;
  110.     return 0;
  111.     }
  112.  
  113.     if { $board == "host" } {
  114.     if { [info exists host_board] && $host_board != "" } {
  115.         verbose "board is $board, is remote" 3;
  116.         return 1;
  117.     } else {
  118.         verbose "board is $board, host is local" 3;
  119.         return 0;
  120.     }
  121.     }
  122.  
  123.     if { $board == "target" } {
  124.     global current_target_name
  125.  
  126.     if [info exists current_target_name] {
  127.         # This shouldn't happen, but we'll be paranoid anyway.
  128.         if { $current_target_name != "target" } {
  129.         return [is_remote $current_target_name];
  130.         }
  131.     }
  132.     return 0;
  133.     }
  134.     if [board_info $board exists isremote] {
  135.     verbose "board is $board, isremote is [board_info $board isremote]" 3;
  136.     return [board_info $board isremote];
  137.     }
  138.     return 1;
  139. }
  140. #
  141. # If this is a canadian (3 way) cross. This means the tools are
  142. # being built with a cross compiler for another host.
  143. #
  144. proc is3way {} {
  145.     global host_triplet
  146.     global build_triplet
  147.     
  148.     if ![info exists build_triplet] {
  149.     set build_triplet ${host_triplet}
  150.     }
  151.     verbose "Checking $host_triplet against $build_triplet" 2
  152.     if { "$build_triplet" == "$host_triplet" } {
  153.     return 0
  154.     }
  155.     return 1
  156. }
  157.  
  158. #
  159. # Check host triplet for pattern
  160. #
  161. # With no arguments it returns the triplet string.
  162. #
  163. proc ishost { pattern } {
  164.     global host_triplet
  165.     
  166.     if [string match "" $pattern] {
  167.     return $host_triplet
  168.     }
  169.     verbose "Checking pattern \"$pattern\" with $host_triplet" 2
  170.     
  171.     if [string match "$pattern" $host_triplet] {
  172.     return 1
  173.     } else {
  174.     return 0
  175.     }
  176. }
  177.  
  178. #
  179. # Check target triplet for pattern
  180. #
  181. # With no arguments it returns the triplet string.
  182. # Returns 1 if the target looked for, or 0 if not.
  183. #
  184. proc istarget { args } {
  185.     global target_triplet
  186.     
  187.     # if no arg, return the config string
  188.     if [string match "" $args] {
  189.     if [info exists target_triplet] {
  190.         return $target_triplet
  191.     } else {
  192.         perror "No target configuration names found."
  193.     }
  194.     }
  195.  
  196.     # now check against the cannonical name
  197.     if [info exists target_triplet] {
  198.     verbose "Checking \"$args\" against \"$target_triplet\"" 2
  199.     if [string match "$args" $target_triplet] {
  200.         return 1
  201.     }
  202.     }
  203.  
  204.     # nope, no match
  205.     return 0
  206. }
  207.  
  208. #
  209. # Check to see if we're running the tests in a native environment
  210. #
  211. # Returns 1 if running native, 0 if on a target.
  212. #
  213. proc isnative { } {
  214.     global target_triplet
  215.     global build_triplet
  216.     
  217.     if [string match $build_triplet $target_triplet] {
  218.     return 1
  219.     }
  220.     return 0
  221. }
  222.  
  223. #
  224. # unknown -- called by expect if a proc is called that doesn't exist
  225. #
  226. proc unknown { args } {
  227.     global errorCode
  228.     global errorInfo
  229.     global exit_status
  230.  
  231.     clone_output "ERROR: (DejaGnu) proc \"$args\" does not exist."
  232.     if [info exists errorCode] {
  233.         send_error "The error code is $errorCode\n"
  234.     }
  235.     if [info exists errorInfo] {
  236.         send_error "The info on the error is:\n$errorInfo\n"
  237.     }
  238.  
  239.     set exit_status 1;
  240.     log_and_exit;
  241. }
  242.  
  243. #
  244. # Print output to stdout (or stderr) and to log file
  245. #
  246. # If the --all flag (-a) option was used then all messages go the the screen.
  247. # Without this, all messages that start with a keyword are written only to the
  248. # detail log file.  All messages that go to the screen will also appear in the
  249. # detail log.  This should only be used by the framework itself using pass,
  250. # fail, xpass, xfail, warning, perror, note, untested, unresolved, or
  251. # unsupported procedures.
  252. #
  253. proc clone_output { message } {
  254.     global sum_file
  255.     global all_flag
  256.     
  257.     if { $sum_file != "" } {
  258.     puts $sum_file "$message"
  259.     }
  260.  
  261.     regsub "^\[ \t\]*(\[^ \t\]+).*$" "$message" "\\1" firstword;
  262.     case "$firstword" in {
  263.     {"PASS:" "XFAIL:" "UNRESOLVED:" "UNSUPPORTED:" "UNTESTED:"} {
  264.         if $all_flag {
  265.         send_user "$message\n"
  266.         return "$message"
  267.         } else {
  268.         send_log "$message\n"
  269.         }
  270.     }
  271.     {"ERROR:" "WARNING:" "NOTE:"} {
  272.         send_error "$message\n"
  273.         return "$message"
  274.     }
  275.     default {
  276.         send_user "$message\n"
  277.         return "$message"
  278.     }
  279.     }
  280. }
  281.  
  282. #
  283. # Reset a few counters.
  284. #
  285. proc reset_vars {} {
  286.     global test_names test_counts;
  287.     global warncnt errcnt;
  288.  
  289.     # other miscellaneous variables
  290.     global prms_id
  291.     global bug_id
  292.     
  293.     # reset them all
  294.     set prms_id    0;
  295.     set bug_id    0;
  296.     set warncnt 0;
  297.     set errcnt  0;
  298.     foreach x $test_names {
  299.     set test_counts($x,count) 0;
  300.     }
  301.  
  302.     # Variables local to this file.
  303.     global warning_threshold perror_threshold
  304.     set warning_threshold 3
  305.     set perror_threshold 1
  306. }
  307.  
  308. proc log_and_exit {} {
  309.     global exit_status;
  310.     global tool mail_logs outdir mailing_list;
  311.  
  312.     log_summary total;
  313.     # extract version number
  314.     if {[info procs ${tool}_version] != ""} {
  315.     if {[catch "${tool}_version" output]} {
  316.         warning "${tool}_version failed:\n$output"
  317.     }
  318.     }
  319.     close_logs
  320.     cleanup
  321.     verbose -log "runtest completed at [timestamp -format %c]"
  322.     if $mail_logs {
  323.     mail_file $outdir/$tool.sum $mailing_list "Dejagnu Summary Log"
  324.     }
  325.     remote_close host
  326.     remote_close target
  327.     exit $exit_status
  328. }
  329. #
  330. # Print summary of all pass/fail counts
  331. #
  332. proc log_summary { args } {
  333.     global tool
  334.     global sum_file
  335.     global exit_status
  336.     global mail_logs
  337.     global outdir
  338.     global mailing_list
  339.     global current_target_name
  340.     global test_counts;
  341.     global testcnt;
  342.  
  343.     if { [llength $args] == 0 } {
  344.     set which "count";
  345.     } else {
  346.     set which [lindex $args 0];
  347.     }
  348.  
  349.     if { [llength $args] == 0 } {
  350.     clone_output "\n\t\t=== $tool Summary for $current_target_name ===\n"
  351.     } else {
  352.     clone_output "\n\t\t=== $tool Summary ===\n"
  353.     }
  354.  
  355.     # If the tool set `testcnt', it wants us to do a sanity check on the
  356.     # total count, so compare the reported number of testcases with the
  357.     # expected number.  Maintaining an accurate count in `testcnt' isn't easy
  358.     # so it's not clear how often this will be used.
  359.     if [info exists testcnt] {
  360.     if { $testcnt > 0 } {
  361.         set totlcnt 0;
  362.         # total all the testcases reported
  363.         foreach x { FAIL PASS XFAIL XPASS UNTESTED UNRESOLVED UNSUPPORTED } {
  364.         incr totlcnt test_counts($x,$which);
  365.         }
  366.         set testcnt test_counts(total,$which);
  367.         
  368.         if { $testcnt>$totlcnt || $testcnt<$totlcnt } {
  369.         if { $testcnt > $totlcnt } {
  370.             set mismatch "unreported  [expr $testcnt-$totlcnt]"
  371.         }
  372.         if { $testcnt < $totlcnt } {
  373.             set mismatch "misreported [expr $totlcnt-$testcnt]"
  374.         }
  375.         } else {
  376.         verbose "# of testcases run         $testcnt"
  377.         }
  378.  
  379.         if [info exists mismatch] {
  380.         clone_output "### ERROR: totals do not equal number of testcases run"
  381.         clone_output "### ERROR: # of testcases expected    $testcnt"
  382.         clone_output "### ERROR: # of testcases reported    $totlcnt"
  383.         clone_output "### ERROR: # of testcases $mismatch\n"
  384.         }
  385.     }
  386.     }
  387.     foreach x { PASS FAIL XPASS XFAIL UNRESOLVED UNTESTED UNSUPPORTED } {
  388.     set val $test_counts($x,$which);
  389.     if { $val > 0 } {
  390.         set mess "# of $test_counts($x,name)";
  391.         if { [string length $mess] < 24 } {
  392.         append mess "\t";
  393.         }
  394.         clone_output "$mess\t$val";
  395.     }
  396.     }
  397. }
  398.  
  399. #
  400. # Close all open files, remove temp file and core files
  401. #
  402. proc cleanup {} {
  403.     global sum_file
  404.     global exit_status
  405.     global done_list
  406.     global base_dir
  407.     global subdir
  408.     
  409.     #catch "exec rm -f [glob xgdb core *.x *.o *_soc a.out]"
  410.     #catch "exec rm -f [glob -nocomplain $subdir/*.o $subdir/*.x $subdir/*_soc]"
  411. }
  412.  
  413. #
  414. # Setup a flag to control whether a failure is expected or not
  415. #
  416. # Multiple target triplet patterns can be specified for targets
  417. # for which the test fails.  A decimal number can be specified,
  418. # which is the PRMS number.
  419. #
  420. proc setup_xfail { args } {
  421.     global xfail_flag
  422.     global xfail_prms
  423.     
  424.     set xfail_prms 0
  425.     set argc [ llength $args ]
  426.     for { set i 0 } { $i < $argc } { incr i } {
  427.     set sub_arg [ lindex $args $i ]
  428.     # is a prms number. we assume this is a number with no characters
  429.     if [regexp "^\[0-9\]+$" $sub_arg] { 
  430.         set xfail_prms $sub_arg
  431.         continue
  432.     }
  433.     if [istarget $sub_arg] {
  434.         set xfail_flag 1
  435.         continue
  436.     }
  437.     }
  438. }
  439.  
  440. #
  441. # Clear the xfail flag for a particular target
  442. #
  443. proc clear_xfail { args } {
  444.     global xfail_flag
  445.     global xfail_prms
  446.     
  447.     set argc [ llength $args ]
  448.     for { set i 0 } { $i < $argc } { incr i } {
  449.     set sub_arg [ lindex $args $i ]
  450.     case $sub_arg in {
  451.         "*-*-*" {            # is a configuration triplet
  452.         if [istarget $sub_arg] {
  453.             set xfail_flag 0
  454.             set xfail_prms 0
  455.         }
  456.         continue
  457.         }
  458.     }
  459.     }
  460. }
  461.  
  462. #
  463. # Record that a test has passed or failed (perhaps unexpectedly)
  464. #
  465. # This is an internal procedure, only used in this file.
  466. #
  467. proc record_test { type message args } {
  468.     global exit_status
  469.     global prms_id bug_id
  470.     global xfail_flag xfail_prms
  471.     global errcnt warncnt
  472.     global warning_threshold perror_threshold
  473.     global pf_prefix
  474.  
  475.     if { [llength $args] > 0 } {
  476.     set count [lindex $args 0];
  477.     } else {
  478.     set count 1;
  479.     }
  480.     if [info exists pf_prefix] {
  481.     set message [concat $pf_prefix " " $message];
  482.     }
  483.  
  484.     # If we have too many warnings or errors,
  485.     # the output of the test can't be considered correct.
  486.     if { $warning_threshold > 0 && $warncnt >= $warning_threshold
  487.      || $perror_threshold > 0 && $errcnt >= $perror_threshold } {
  488.     # Reset these first to prevent infinite recursion.
  489.     set warncnt 0
  490.     set errcnt  0
  491.     unresolved $message
  492.     return
  493.     }
  494.  
  495.     incr_count $type;
  496.  
  497.     switch $type {
  498.     PASS {
  499.         if $prms_id {
  500.         set message [concat $message "\t(PRMS $prms_id)"]
  501.         }
  502.     }
  503.     FAIL {
  504.         set exit_status 1
  505.         if $prms_id {
  506.         set message [concat $message "\t(PRMS $prms_id)"]
  507.         }
  508.     }
  509.     XPASS {
  510.         set exit_status 1
  511.         if { $xfail_prms != 0 } {
  512.         set message [concat $message "\t(PRMS $xfail_prms)"]
  513.         }
  514.     }
  515.     XFAIL {
  516.         if { $xfail_prms != 0 } {
  517.         set message [concat $message "\t(PRMS $xfail_prms)"]
  518.         }
  519.     }
  520.     UNTESTED {
  521.         # The only reason we look at the xfail stuff is to pick up
  522.         # `xfail_prms'.
  523.         if { $xfail_flag && $xfail_prms != 0 } {
  524.         set message [concat $message "\t(PRMS $xfail_prms)"]
  525.         } elseif $prms_id {
  526.         set message [concat $message "\t(PRMS $prms_id)"]
  527.         }
  528.     }
  529.     UNRESOLVED {
  530.         set exit_status 1
  531.         # The only reason we look at the xfail stuff is to pick up
  532.         # `xfail_prms'.
  533.         if { $xfail_flag && $xfail_prms != 0 } {
  534.         set message [concat $message "\t(PRMS $xfail_prms)"]
  535.         } elseif $prms_id {
  536.         set message [concat $message "\t(PRMS $prms_id)"]
  537.         }
  538.     }
  539.     UNSUPPORTED {
  540.         # The only reason we look at the xfail stuff is to pick up
  541.         # `xfail_prms'.
  542.         if { $xfail_flag && $xfail_prms != 0 } {
  543.         set message [concat $message "\t(PRMS $xfail_prms)"]
  544.         } elseif $prms_id {
  545.         set message [concat $message "\t(PRMS $prms_id)"]
  546.         }
  547.     }
  548.     default {
  549.         perror "record_test called with bad type `$type'"
  550.         set errcnt 0
  551.         return
  552.     }
  553.     }
  554.  
  555.     if $bug_id {
  556.     set message [concat $message "\t(BUG $bug_id)"]
  557.     }
  558.  
  559.     global multipass_name
  560.     if { $multipass_name != "" } {
  561.     clone_output "$type: $multipass_name: $message"
  562.     } else {
  563.     clone_output "$type: $message"
  564.     }
  565.     
  566.     # Reset these so they're ready for the next test case.  We don't reset
  567.     # prms_id or bug_id here.  There may be multiple tests for them.  Instead
  568.     # they are reset in the main loop after each test.  It is also the
  569.     # testsuite driver's responsibility to reset them after each testcase.
  570.     set warncnt 0
  571.     set errcnt 0
  572.     set xfail_flag 0
  573.     set xfail_prms 0
  574. }
  575.  
  576. #
  577. # Record that a test has passed
  578. #
  579. proc pass { message } {
  580.     global xfail_flag
  581.  
  582.     if $xfail_flag {
  583.     record_test XPASS $message
  584.     } else {
  585.     record_test PASS $message
  586.     }
  587. }
  588.  
  589. #
  590. # Record that a test has failed
  591. #
  592. proc fail { message } {
  593.     global xfail_flag
  594.  
  595.     if $xfail_flag {
  596.     record_test XFAIL $message
  597.     } else {
  598.     record_test FAIL $message
  599.     }
  600. }
  601.  
  602. #
  603. # Record that a test has passed unexpectedly
  604. #
  605. proc xpass { message } {
  606.     record_test XPASS $message
  607. }
  608.  
  609. #
  610. # Record that a test has failed unexpectedly
  611. #
  612. proc xfail { message } {
  613.     record_test XFAIL $message
  614. }
  615.  
  616. #
  617. # Set warning threshold
  618. #
  619. proc set_warning_threshold { threshold } {
  620.     set warning_threshold $threshold
  621. }
  622.  
  623. #
  624. # Get warning threshold
  625. #
  626. proc get_warning_threshold { } {
  627.     return $warning_threshold
  628. }
  629.  
  630. #
  631. # Prints warning messages
  632. # These are warnings from the framework, not from the tools being tested.
  633. # It takes a string, and an optional number and returns nothing.
  634. #
  635. proc warning { args } {
  636.     global warncnt
  637.  
  638.     if { [llength $args] > 1 } {
  639.     set warncnt [lindex $args 1]
  640.     } else {
  641.     incr warncnt
  642.     }
  643.     set message [lindex $args 0]
  644.     
  645.     clone_output "WARNING: $message"
  646.  
  647.     global errorInfo
  648.     if [info exists errorInfo] {
  649.     unset errorInfo
  650.     }
  651. }
  652.  
  653. #
  654. # Prints error messages
  655. # These are errors from the framework, not from the tools being tested. 
  656. # It takes a string, and an optional number and returns nothing.
  657. #
  658. proc perror { args } {
  659.     global errcnt
  660.  
  661.     if { [llength $args] > 1 } {
  662.     set errcnt [lindex $args 1]
  663.     } else {
  664.     incr errcnt
  665.     }
  666.     set message [lindex $args 0]
  667.     
  668.     clone_output "ERROR: $message"
  669.  
  670.     global errorInfo
  671.     if [info exists errorInfo] {
  672.     unset errorInfo
  673.     }
  674. }
  675.  
  676. #
  677. # Prints informational messages
  678. #
  679. # These are messages from the framework, not from the tools being tested.
  680. # This means that it is currently illegal to call this proc outside
  681. # of dejagnu proper.
  682. #
  683. proc note { message } {
  684.     clone_output "NOTE: $message"
  685.  
  686.     # ??? It's not clear whether we should do this.  Let's not, and only do
  687.     # so if we find a real need for it.
  688.     #global errorInfo
  689.     #if [info exists errorInfo] {
  690.     #    unset errorInfo
  691.     #}
  692. }
  693.  
  694. #
  695. # untested -- mark the test case as untested
  696. #
  697. proc untested { message } {
  698.     record_test UNTESTED $message
  699. }
  700.  
  701. #
  702. # Mark the test case as unresolved
  703. #
  704. proc unresolved { message } {
  705.     record_test UNRESOLVED $message
  706. }
  707.  
  708. #
  709. # Mark the test case as unsupported
  710. #
  711. # Usually this is used for a test that is missing OS support.
  712. #
  713. proc unsupported { message } {
  714.     record_test UNSUPPORTED $message
  715. }
  716.  
  717. #
  718. # Set up the values in the test_counts array (name and initial totals).
  719. #
  720. proc init_testcounts { } {
  721.     global test_counts test_names;
  722.     set test_counts(TOTAL,name) "testcases run"
  723.     set test_counts(PASS,name) "expected passes"
  724.     set test_counts(FAIL,name) "unexpected failures"
  725.     set test_counts(XFAIL,name) "expected failures"
  726.     set test_counts(XPASS,name) "unexpected successes"
  727.     set test_counts(WARNING,name) "warnings"
  728.     set test_counts(ERROR,name) "errors"
  729.     set test_counts(UNSUPPORTED,name) "unsupported tests"
  730.     set test_counts(UNRESOLVED,name) "unresolved testcases"
  731.     set test_counts(UNTESTED,name) "untested testcases"
  732.     set j "";
  733.  
  734.     foreach i [lsort [array names test_counts]] {
  735.     regsub ",.*$" "$i" "" i;
  736.     if { $i == $j } {
  737.         continue;
  738.     }
  739.     set test_counts($i,total) 0;
  740.     lappend test_names $i;
  741.     set j $i;
  742.     }
  743. }
  744.  
  745. #
  746. # Increment NAME in the test_counts array; the amount to increment can be
  747. # is optional (defaults to 1).
  748. #
  749. proc incr_count { name args } {
  750.     global test_counts;
  751.  
  752.     if { [llength $args] == 0 } {
  753.     set count 1;
  754.     } else {
  755.     set count [lindex $args 0];
  756.     }
  757.     if [info exists test_counts($name,count)] {
  758.     incr test_counts($name,count) $count;
  759.     incr test_counts($name,total) $count;
  760.     } else {
  761.     perror "$name doesn't exist in incr_count"
  762.     }
  763. }
  764.  
  765.  
  766. #
  767. # Create an exp_continue proc if it doesn't exist
  768. #
  769. # For compatablity with old versions.
  770. #
  771. global argv0
  772. if ![info exists argv0] {
  773.     proc exp_continue { } {
  774.     continue -expect
  775.     }
  776. }
  777.